package com.ideas.impl.mianshi;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 有3个人（线程）针对同一个商品展开竞价，商品起拍价格为100元，每个元都有自己的预算，出价不能超过预算，3个人轮流
 * 争抢式出价，后出的价格统一比前出的价格大100元，模拟实现这个过程。
 * @Description
 * @Author lijian.wu
 * @Date 2025-1-21 10:18
 */
public class AuctionTest {
    private static int currentPrice = 100; // 商品起拍价格&最新最高出价
    private static final int BID_INCREMENT = 100; // 出价增量
    private static final Lock lock = new ReentrantLock();
    //退出的人数
    private static int withdrawn = 0;

    public static void main(String[] args) {

        // 创建竞拍者线程
        Thread bidderA = new Thread(new Bidder("Bidder A", 500));
        Thread bidderB = new Thread(new Bidder("Bidder B", 900));
        Thread bidderC = new Thread(new Bidder("Bidder C", 300));

        // 启动竞拍者线程
        bidderA.start();
        bidderB.start();
        bidderC.start();
    }

    // 竞拍者类
    static class Bidder implements Runnable {
        private final String name;
        private final int budget;
        //当前线程的出价
        private int price = 0;

        public Bidder(String name, int budget) {
            this.name = name;
            this.budget = budget;
        }

        @Override
        public void run() {
            while (true) {
                lock.lock();
                try {
                    //检查是否其他人都退出了
                    if(withdrawn == 2){
                        System.out.println(name + " 竞得.花费了 "+ price + "元.");
                        break;
                    }
                    if(price == currentPrice){
                        //不能连续出价
                        continue;
                    }
                    if (currentPrice + BID_INCREMENT <= budget) {
                        currentPrice += BID_INCREMENT;
                        price = currentPrice;
                        System.out.println(name + " 出价 " + currentPrice + " 元.");
                    } else {
                        System.out.println(name + " 超出预算，退出.");
                        withdrawn++;
                        break;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }
    }
}
